package com.kcloud.commons.authorization.settings.biz.web;

import com.kcloud.commons.authorization.AuthorizationCacheHolder;
import com.kcloud.commons.authorization.AuthorizationConfig;
import com.kcloud.commons.authorization.constants.AuthorizationConstants;
import com.kcloud.commons.authorization.settings.biz.entity.*;
import com.kcloud.commons.authorization.settings.biz.service.BizSettingsService;
import com.kcloud.commons.entity.control.Attribute;
import com.kcloud.commons.entity.control.AttributeGroup;
import com.kcloud.commons.entity.control.BizDomain;
import com.kcloud.commons.entity.json.JsonListObject;
import com.kcloud.commons.entity.json.JsonObject;
import com.kcloud.commons.entity.json.JsonSuccessObject;
import io.swagger.annotations.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 业务设置web接口
 *
 * @author songhuiqing
 */

@Api(tags = "业务体系设置接口")
@RestController
@RequestMapping("/bizSettings")
public class BizSettingsController {

    @Autowired
    private BizSettingsService bizSettingsService;

    @Autowired
    private AuthorizationConfig authorizationConfig;


    @ApiOperation(value = "查询业务域")
    @GetMapping("/domains")
    public JsonObject getDomains() {

        List<BizDomain> domains = authorizationConfig.getInitDomains().stream().map(cls -> {
            return new BizDomain();
        }).collect(Collectors.toList());
        return new JsonSuccessObject(domains);
    }
    /**
     * 新增业务实体
     */
    @ApiOperation(value = "新增业务实体", notes = "在业务域下新增业务实体")
    @ApiImplicitParams({
            @ApiImplicitParam(name = AuthorizationConstants.HEADER_KEY_BIZ_DOMAIN_CODE, value = "业务域编码", paramType = "header", required = true),
            @ApiImplicitParam(name = "title", value = "业务实体名称", paramType = "query", required = true)
    })
    @PostMapping("/addBizEntity")
    public JsonObject addBizEntity(@ApiIgnore BizEntity entity, @RequestHeader(AuthorizationConstants.HEADER_KEY_BIZ_DOMAIN_CODE) String bizDomainCode) {
        entity.setBizDomainCode(bizDomainCode);
        bizSettingsService.addBizEntity(entity);
        return JsonSuccessObject.SUCCESS;
    }

    /**
     * 更新业务实体
     */
    @ApiOperation(value = "更新业务实体")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "业务实体ID", paramType = "query", required = true),
            @ApiImplicitParam(name = "title", value = "业务实体名称", paramType = "query", required = true),
            @ApiImplicitParam(name = AuthorizationConstants.HEADER_KEY_BIZ_DOMAIN_CODE, value = "业务域编码", paramType = "header", required = true)
    })
    @PutMapping("/updateBizEntity")
    public JsonObject updateBizEntity(@ApiIgnore BizEntity entity) {
        bizSettingsService.updateBizEntity(entity);
        return JsonSuccessObject.SUCCESS;
    }

    /**
     * 删除业务实体
     */
    @ApiOperation(value = "删除业务实体")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "业务实体ID", paramType = "query", required = true, allowMultiple = true),
            @ApiImplicitParam(name = AuthorizationConstants.HEADER_KEY_BIZ_DOMAIN_CODE, value = "业务域编码", paramType = "header", required = true)
    })
    @DeleteMapping("deleteBizEntity")
    public JsonObject deleteBizEntity(String[] ids) {
        bizSettingsService.deleteBizEntity(ids);
        return JsonSuccessObject.SUCCESS;
    }

    /**
     * 查询业务域下的业务实体
     */
    @ApiOperation(value = "查询业务域下的业务实体")
    @ApiImplicitParams({
            @ApiImplicitParam(name = AuthorizationConstants.HEADER_KEY_BIZ_DOMAIN_CODE, value = "业务域编码", paramType = "header", required = true)
    })
    @GetMapping("/listBizEntity")
    public JsonListObject listBizEntity() {

        return new JsonListObject(bizSettingsService.listBizEntity());
    }

    /**
     * 新增业务功能
     */
    @ApiOperation(value = "新增业务功能")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "bizEntityId", value = "业务实体id", paramType = "query", required = true),
            @ApiImplicitParam(name = "funcCode", value = "功能编码", paramType = "query", required = true),
            @ApiImplicitParam(name = "title", value = "功能名称", paramType = "query", required = true),
            @ApiImplicitParam(name = AuthorizationConstants.HEADER_KEY_BIZ_DOMAIN_CODE, value = "业务域编码", paramType = "header", required = true)
    })
    @PostMapping("/addBizFunc")
    public JsonObject addBizFunction(@ApiIgnore BizFunction function) {
        bizSettingsService.addBizFunction(function);
        return JsonSuccessObject.SUCCESS;
    }

    /**
     * 批量新增业务功能
     */
    @ApiOperation(value = "新增业务功能")
    @ApiImplicitParams({
            @ApiImplicitParam(name = AuthorizationConstants.HEADER_KEY_BIZ_DOMAIN_CODE, value = "业务域编码", paramType = "header", required = true)
    })
    @PostMapping("/batchAddBizFunc")
    public JsonObject addBizFunction(@ApiParam @RequestBody List<BizFunction> functions) {
        functions.forEach(function -> bizSettingsService.addBizFunction(function));
        return JsonSuccessObject.SUCCESS;
    }

    /**
     * 删除业务功能
     */
    @ApiOperation(value = "删除业务功能")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "业务实体id", paramType = "query", required = true, allowMultiple = true),
            @ApiImplicitParam(name = AuthorizationConstants.HEADER_KEY_BIZ_DOMAIN_CODE, value = "业务域编码", paramType = "header", required = true)
    })
    @DeleteMapping("/deleteBizFunc")
    public JsonObject deleteBizFunction(String[] ids) {
        bizSettingsService.deleteBizFunction(ids);
        return JsonSuccessObject.SUCCESS;
    }

    /**
     * 根据业务实体id查询业务功能列表
     */
    @ApiOperation(value = "根据业务实体id查询业务功能列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "bizEntityId", value = "业务实体id", paramType = "query", required = true),
            @ApiImplicitParam(name = AuthorizationConstants.HEADER_KEY_BIZ_DOMAIN_CODE, value = "业务域编码", paramType = "header", required = true)
    })
    @GetMapping("/listBizFunc")
    public JsonListObject<List<BizFunction>> listBizFunction(String bizEntityId) {

        return new JsonListObject(bizSettingsService.listBizFunction(bizEntityId));
    }

    /**
     * 根据业务功能id查询业务功能列表
     */
    @ApiOperation(value = "根据业务实体id查询业务功能列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "bizFunctionIds", value = "业务功能id数组", paramType = "query", allowMultiple = true, required = true),
            @ApiImplicitParam(name = AuthorizationConstants.HEADER_KEY_BIZ_DOMAIN_CODE, value = "业务域编码", paramType = "header", required = true)
    })
    @GetMapping("/listBizFuncByIds")
    public JsonObject<List<BizFunction>> listBizFunction(String[] bizFunctionIds) {

        return new JsonListObject(bizSettingsService.listBizFunction(bizFunctionIds));
    }

    /**
     * 更新业务功能，含功能属性及功能操作
     */
    @ApiOperation(value = "更新业务功能，含功能属性及功能操作")
    @ApiImplicitParams({
            @ApiImplicitParam(name = AuthorizationConstants.HEADER_KEY_BIZ_DOMAIN_CODE, value = "业务域编码", paramType = "header", required = true)
    })
    @PutMapping("/updateBizFunc")
    public JsonObject updateBizFunction(@ApiParam @RequestBody BizFunction function) {
        function.setAttributeText(null);
        function.setOperationText(null);
        bizSettingsService.updateBizFunction(function);
        return JsonSuccessObject.SUCCESS;
    }

    /**
     * 根据业务功能ID查询业务功能，含功能属性及操作
     */
    @ApiOperation(value = "根据业务功能ID查询业务功能，含功能属性及操作")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "业务功能id", paramType = "query", required = true),
            @ApiImplicitParam(name = AuthorizationConstants.HEADER_KEY_BIZ_DOMAIN_CODE, value = "业务域编码", paramType = "header", required = true)
    })
    @GetMapping("/getBizFunc")
    public JsonObject getBizFunction(String id) {
        return new JsonSuccessObject(bizSettingsService.getBizFunction(id));
    }

    /**
     * 新增业务功能权限
     */
    @ApiOperation(value = "新增业务功能权限")
    @PostMapping("/ctrlUnitBizFunction")
    public JsonObject addCtrlUnitBizFunction(@ApiParam @RequestBody CtrlUnitBizFunction ctrlUnitBizFunction) {
        bizSettingsService.addBizFunctionToUser(ctrlUnitBizFunction);
        return JsonSuccessObject.SUCCESS;
    }


    @ApiOperation(value = "查询用户功能权限")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "userId", value = "用户ID", paramType = "query", required = true),
            @ApiImplicitParam(name = "configId", value = "业务功能配置ID", paramType = "query", required = true),
            @ApiImplicitParam(name = AuthorizationConstants.HEADER_KEY_BIZ_DOMAIN_CODE, value = "业务域编码", paramType = "header", required = true)
    })
    @GetMapping("/getFunctionAttrs")
    public JsonObject<FrontendFunction> getFrontendFunction(String userId, String configId) {

        //TODO 没想好如何缓存，所有数据暂时直接查询数据库
        FrontendFunction f = new FrontendFunction();
        BizFunction bizFunction = bizSettingsService.getBizFunction(configId);
//        List<UserBizFunction> ubfs = bizSettingsService.listUserBizFunction(userId, configId);
        if(bizFunction != null) {
            List<AttributeGroup> list = new ArrayList<>();
            List<AttributeGroup> queryList = new ArrayList<>();
            List<AttributeGroup> operationList = new ArrayList<>();
            List<AttributeGroup> attributeGroups = bizFunction.getAttributeGroups();
            if(attributeGroups != null && attributeGroups.size() != 0) {
                attributeGroups.forEach(g -> {
                    AttributeGroup listAttrGrp = new AttributeGroup();
                    AttributeGroup queryAttrGrp = new AttributeGroup();
                    AttributeGroup operationAttrGrp = new AttributeGroup();
                    listAttrGrp.setGroupCode(g.getGroupCode());
                    listAttrGrp.setGroupName(g.getGroupName());
                    listAttrGrp.setGroupType(g.getGroupType());
                    BeanUtils.copyProperties(listAttrGrp, queryAttrGrp);
                    BeanUtils.copyProperties(listAttrGrp, operationAttrGrp);

                    //列表属性集合
                    List<Attribute> listAttrList = new ArrayList<>();
                    //列表属性集合
                    List<Attribute> queryAttrList = new ArrayList<>();
                    //全局操作属性集合
                    List<Attribute> optAttrList = new ArrayList<>();
                    //表单属性集
                    g.getAttributes().forEach(attr -> {

                        if (Attribute.ATTR_TYPE_GLOBAL_OPT.equalsIgnoreCase(attr.getAttrType())) {
                            optAttrList.add(attr);
                        } else {
                            listAttrList.add(attr);
                            if (attr.getQuery()) {
                                queryAttrList.add(attr);
                            }
                        }

                    });
                    //排序处理
                    if(listAttrList != null && listAttrList.size() != 0) {
                        listAttrGrp.setAttributes(listAttrList.stream().sorted(Comparator.comparingInt(Attribute::getTableHeaderOrder)).collect(Collectors.toList()));
                    }
                    if(queryAttrList != null && queryAttrList.size() != 0) {
                        queryAttrGrp.setAttributes(queryAttrList.stream().sorted(Comparator.comparingInt(Attribute::getTableHeaderOrder)).collect(Collectors.toList()));
                    }
                    if(optAttrList != null && optAttrList.size() != 0) {
                        operationAttrGrp.setAttributes(optAttrList.stream().sorted(Comparator.comparingInt(Attribute::getTableHeaderOrder)).collect(Collectors.toList()));
                    }

                    list.add(listAttrGrp);
                    queryList.add(queryAttrGrp);
                    operationList.add(operationAttrGrp);
                });
            }
//            f.setFormLayout(formLayout);
//            f.setList(list);
            f.setSearchList(queryList);
            f.setData(list);
            f.setOperatorList(operationList);
        }
        return new JsonSuccessObject<>(f);
    }


}
